package xcmd

import (
	"errors"
	"fmt"
	"os"
	"strings"

	"gitee.com/xiaoyutab/xgotool/xstring"
)

// 二维码生成的配置信息
type QrcodeConfig struct {
	Size       uint   // 二维码大小（多少个像素点）【specify module size in dots (pixels). (default=3)】
	Level      string // 二维码质量【specify error correction level from L (lowest) to H (highest){LMQH}. (default=L)】
	Border     uint   // 外边距大小（多少个像素点）【specify the width of the margins. (default=2))】
	Background string // 背景色格式为RRGGBB[AA]，默认：FFFFFF
	Foreground string // 前景色格式为RRGGBB[AA]，默认：000000
	Replace    bool   // 若存在输出文件则直接覆盖？【默认false，返回错误信息】
}

// 转换为二维码
//
//	input	待转换的字符串
//	output	二维码文件存储位置（生成的文件为png格式图片，所以建议直接传入图片后缀png）
//	conf	二维码配置项
func Qrcode(input, output string, conf *QrcodeConfig) error {
	if err := CheckCommand("qrencode"); err != nil {
		return err
	}
	if input == "" {
		return errors.New("输入内容不能为空")
	}
	if conf == nil {
		conf = &QrcodeConfig{}
	}
	if _, err := os.Stat(output); !conf.Replace && err == nil {
		// 如果输出文件存在的话就直接返回成功
		return errors.New("输出文件已存在")
	}
	// 配置默认值
	if conf.Background == "" {
		conf.Background = "FFFFFF"
	}
	if conf.Foreground == "" {
		conf.Foreground = "000000"
	}
	if conf.Level == "" {
		conf.Level = "L"
	}
	if conf.Size == 0 {
		conf.Size = 3
	}
	if conf.Border == 0 {
		conf.Border = 2
	}
	// 生成二维码
	_, err := Exec(GetCommand("qrencode"),
		"-o", output,
		"-m", fmt.Sprintf("%d", conf.Border),
		"-l", conf.Level,
		"-s", fmt.Sprintf("%d", conf.Size),
		"--background", conf.Background,
		"--foreground", conf.Foreground,
		input,
	)
	return err
}

// 二维码识别
//
//	f	要识别的文件地址[支持输入图片文件地址]
func QrcodeIdentification(f string) (map[string][]string, error) {
	if err := CheckCommand("bash", "zbarimg", "curl"); err != nil {
		return nil, err
	}
	if f == "" {
		return nil, errors.New("输入文件不能为空")
	}
	if len(f) < 6 || f[:4] != "http" {
		// 输入文件不存在
		if _, err := os.Stat(f); err != nil {
			return nil, err
		}
	}
	files := ""
	if len(f) > 6 && f[:5] == "https" {
		// 如果请求的是https网址的话
		files = "/tmp/" + xstring.RandomNo("file_", 3)
		_, err := Exec(GetCommand("curl"), "-o", files, f)
		if err != nil {
			return nil, err
		}
		f = files
	}
	defer func() {
		if files != "" {
			// 删除文件
			os.Remove(files)
		}
	}()
	out, err := Exec(GetCommand("bash"), "-c", fmt.Sprintf("%s --nodbus \"%s\" 2>&1", GetCommand("zbarimg"), f))
	if err != nil {
		return nil, err
	}
	// 读取内容
	s := strings.Split(out, "\n")
	out_map := map[string][]string{}
	for i := 0; i < len(s); i++ {
		if strings.Contains(s[i], ":") {
			l := strings.Index(s[i], ":")
			if s[i][:l] == "ERROR" {
				return nil, errors.New(s[i][l+1:])
			}
			if _, ok := out_map[s[i][0:l]]; !ok {
				out_map[s[i][0:l]] = []string{}
			}
			out_map[s[i][0:l]] = append(out_map[s[i][0:l]], s[i][l+1:])
		}
	}
	return out_map, nil
}
